library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity crc32 is
   port(
      clk, init, enable: in std_logic;
      data: in std_logic_vector(3 downto 0);
      crc_err: out std_logic
   );
end crc32;

architecture arch of crc32 is

signal r_reg, r_next: std_logic_vector(31 downto 0);

begin


process(clk)
begin
	if (clk'event and clk='1') then
		if (init='1') then
			r_reg <= x"ffffffff";
		elsif (enable='1') then
			r_reg <= r_next;
		end if;	
	end if;
end process;

r_next(31) <= r_reg(27);
r_next(30) <= r_reg(26);
r_next(29) <= r_reg(25) xor r_reg(31) xor data(0);
r_next(28) <= r_reg(24) xor r_reg(30) xor data(1);
r_next(27) <= r_reg(23) xor r_reg(29) xor data(2);
r_next(26) <= r_reg(22) xor r_reg(28) xor r_reg(31) xor data(3) xor data(0);
r_next(25) <= r_reg(21) xor r_reg(30) xor r_reg(31) xor data(1) xor data(0);
r_next(24) <= r_reg(20) xor r_reg(29) xor r_reg(30) xor data(2) xor data(1);
r_next(23) <= r_reg(19) xor r_reg(28) xor r_reg(29) xor data(3) xor data(2);
r_next(22) <= r_reg(18) xor r_reg(28) xor data(3);
r_next(21) <= r_reg(17);
r_next(20) <= r_reg(16);
r_next(19) <= r_reg(15) xor r_reg(31) xor data(0);
r_next(18) <= r_reg(14) xor r_reg(30) xor data(1);
r_next(17) <= r_reg(13) xor r_reg(29) xor data(2);
r_next(16) <= r_reg(12) xor r_reg(28) xor data(3);
r_next(15) <= r_reg(11) xor r_reg(31) xor data(0);
r_next(14) <= r_reg(10) xor r_reg(30) xor r_reg(31) xor data(1) xor data(0);
r_next(13) <= r_reg(9) xor r_reg(29) xor r_reg(30) xor r_reg(31) xor data(2) xor data(1) xor data(0);
r_next(12) <= r_reg(8) xor r_reg(28) xor r_reg(29) xor r_reg(30) xor data(3) xor data(2) xor data(1);
r_next(11) <= r_reg(7) xor r_reg(28) xor r_reg(29) xor r_reg(31) xor data(3) xor data(2) xor data(0);
r_next(10) <= r_reg(6) xor r_reg(28) xor r_reg(30) xor r_reg(31) xor data(3) xor data(1) xor data(0);
r_next(9) <= r_reg(5) xor r_reg(29) xor r_reg(30) xor data(2) xor data(1);
r_next(8) <= r_reg(4) xor r_reg(28) xor r_reg(29) xor r_reg(31) xor data(3) xor data(2) xor data(0);
r_next(7) <= r_reg(3) xor r_reg(28) xor r_reg(30) xor r_reg(31) xor data(3) xor data(1) xor data(0);
r_next(6) <= r_reg(2) xor r_reg(29) xor r_reg(30) xor data(2) xor data(1);
r_next(5) <= r_reg(1) xor r_reg(28) xor r_reg(29) xor r_reg(31) xor data(3) xor data(2) xor data(0);
r_next(4) <= r_reg(0) xor r_reg(28) xor r_reg(30) xor r_reg(31) xor data(3) xor data(1) xor data(0);
r_next(3) <= r_reg(29) xor r_reg(30) xor r_reg(31) xor data(2) xor data(1) xor data(0);
r_next(2) <= r_reg(28) xor r_reg(29) xor r_reg(30) xor data(3) xor data(2) xor data(1);
r_next(1) <= r_reg(28) xor r_reg(29) xor data(3) xor data(2);
r_next(0) <= r_reg(28) xor data(3);

crc_err <= '0' when (r_reg = x"c704dd7b") else '1';

end arch;
